﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Awesomium.Core;
using GalaSoft.MvvmLight;
using MusicExplorer.Helper;
using MusicExplorer.Internals;
using MusicExplorer.WebRepository;
using MusicExplorer.WebRepository.Service;
using MusicExplorer.Wrappers;

namespace MusicExplorer.ViewModel
{
    public sealed class PlayerViewModel : ViewModelBase, IDisposable
    {
        private PlayingType m_playingType;
        public PlayingType PlayingType
        {
            get { return m_playingType; }
            set
            {
                if (m_playingType != value)
                {
                    m_playingType = value;
                    RaisePropertyChanged("PlayingType");
                }
            }
        }

        private MainWindowViewModel m_parent;
        public MainWindowViewModel Parent { get { return m_parent; } }

        private System.Timers.Timer m_mediaPlayerTimer;
        private MediaPlayer m_mediaPlayer;

        public PlayerViewModel(MainWindowViewModel parent)
        {
            m_parent = parent;

            m_mediaPlayer = new MediaPlayer() { Volume = 1 };
            m_mediaPlayerTimer = new System.Timers.Timer(500);
            m_mediaPlayerTimer.Elapsed += m_mediaPlayerTimer_Elapsed;
            m_mediaPlayer.MediaFailed += m_mediaPlayer_MediaFailed;
            m_mediaPlayer.MediaOpened += m_mediaPlayer_MediaOpened;

            IsLoading = false;
        }

        #region YOUTUBE
        private string m_webControlHtml;
        public string WebControlHtml
        {
            get { return m_webControlHtml; }
            set
            {
                if (m_webControlHtml != value)
                {
                    m_webControlHtml = value;
                    RaisePropertyChanged("WebControlHtml");
                }
            }
        }

        public void EnableYoutubeLoading()
        {
            IsLoading = true;
        }

        public void DisableYoutubeLoading(bool firstLoading)
        {
            IsLoading = false;
            if (firstLoading)
            {
                ServiceWebRepository.SetTrackIsRead(Parent.TrackList.SelectedTrack.Track);
                Parent.TrackList.SelectedTrack.IsRead = true;
            }
        }

        private const string m_soundcloudHtmlConst =
            @"<iframe id=""sc-widget"" src=""https://w.soundcloud.com/player/?url=http://api.soundcloud.com/tracks/%%TRACK_KEY%%""></iframe>
              <script src=""https://w.soundcloud.com/player/api.js"" type=""text/javascript""></script>
              <script type=""text/javascript"">
              (function(){
                var widgetIframe = document.getElementById('sc-widget'),
                    widget = SC.Widget(widgetIframe);

                widget.bind(SC.Widget.Events.READY, function() {
	              widget.play();
                  widget.bind(SC.Widget.Events.PLAY, function() {
        
                  });
                });
              }());
            </script>";

        private const string m_youtubeHtmlConst =
          @"<!DOCTYPE html>
            <html>
              <body>
                <div id=""player""></div>

                <script>
                    var tag = document.createElement('script');
                    tag.src = ""https://www.youtube.com/iframe_api"";
                    var firstScriptTag = document.getElementsByTagName('script')[0];
                    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

                    var timer;
                    function onPlayerReady(event) {
                        timer = setInterval(sendPosition, 500);
                        event.target.playVideo();
                    }

                    function seekTo(second) {
                        player.pauseVideo();
                        player.seekTo(second);
                        player.playVideo();
                    }

                    function sendPosition() {
                        jsobject.GoToPosition(player.getCurrentTime());
                    }

                    function stopPlaying() {
                        clearInterval(timer);
                    }

                    function onPlayerStateChange(event) {
                        if (event.data == -1 || event.data == 3 || event.data == 2) {
                            jsobject.EnableLoading();
                        }
                        if (event.data == 1 || event.data == 0) {
                            jsobject.DisableLoading(firstLoading);
                            firstLoading = false;
                        }
                    }

                    var player;
                    var firstLoading;
                    function onYouTubeIframeAPIReady() {
                        firstLoading = true;
                        player = new YT.Player('player', {
                            videoId: '%%TRACK_KEY%%',
                            events: {
                                'onReady': onPlayerReady,
                                'onStateChange': onPlayerStateChange
                            }
                        });
                    }

                </script>
              </body>
            </html>";

        #endregion

        #region FUNCTIONS

        public void PlayTrack(TrackWrapper track)
        {
            IsLoading = true;
            Stop();

            DisplayNamePlayedTrack = track.Title;

            try
            {
                CurrentImage = new BitmapImage();
                CurrentImage.BeginInit();
                CurrentImage.UriSource = new Uri(track.Track.track_img_url);
                CurrentImage.DecodePixelWidth = 100;
                CurrentImage.EndInit();
            }
            catch
            {
                CurrentImage = null;
            }

            if (track != null && track.GetTypeWebRepository == Data.TypeWebRepository.YoutubeChannel)
            {
                try
                {
                    m_playingType = PlayingType.WebControl;
                    Mp3Length = track.Track.track_duration.Value;
                    WebControlHtml = m_youtubeHtmlConst.Replace("%%TRACK_KEY%%", track.Track.track_key);
                }
                catch
                {
                    IsLoading = false;
                }
            }
            else if (track != null && track.GetTypeWebRepository == Data.TypeWebRepository.SoundcloudAccount)
            {
                try
                {
                    m_playingType = Internals.PlayingType.WebControl;
                    Mp3Length = track.Track.track_duration.Value;
                    WebControlHtml = m_soundcloudHtmlConst.Replace("%%TRACK_KEY%%", track.Track.track_key);
                }
                catch
                {
                    IsLoading = false;
                }
            }
            else if (track != null)
            {
                try
                {
                    m_playingType = PlayingType.MediaPlayer;
                    m_mediaPlayer.Open(new Uri(track.Track.track_mp3_url));
                }
                catch
                {
                    IsLoading = false;
                }
            }
        }

        public void Stop()
        {
            WebControlHtml = @"<!DOCTYPE html>";
            Mp3Position = 0;
            Mp3Length = 0;
            m_mediaPlayerTimer.Stop();
            m_mediaPlayer.Close();
        }

        public void Reset()
        {
            Stop();
            IsLoading = false;
            CurrentImage = null;
            DisplayNamePlayedTrack = null;
        }

        public void SetMp3Position(long ticks)
        {
            m_mediaPlayerTimer.Stop();
            Mp3Position = ticks;
            m_mediaPlayer.Position = TimeSpan.FromTicks(ticks);
            m_mediaPlayerTimer.Start();
        }

        public void SetMp3YoutubePosition(long seconds)
        {
            Mp3Position = seconds;
        }

        #endregion

        #region MEDIA PLAYER

        void m_mediaPlayer_MediaFailed(object sender, ExceptionEventArgs e)
        {
            m_mediaPlayer.Close();
            m_mediaPlayerTimer.Stop();
            Mp3Position = 0;
            Mp3Length = 0;
            IsLoading = false;
        }

        void m_mediaPlayer_MediaOpened(object sender, EventArgs e)
        {
            m_mediaPlayerTimer.Start();
            m_mediaPlayer.Play();
            if (m_mediaPlayer.NaturalDuration.HasTimeSpan)
                Mp3Length = m_mediaPlayer.NaturalDuration.TimeSpan.Ticks;
            ServiceWebRepository.SetTrackIsRead(Parent.TrackList.SelectedTrack.Track);
            Parent.TrackList.SelectedTrack.IsRead = true;
            IsLoading = false;
        }

        void m_mediaPlayerTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            MusicExplorerHelper.ExecuteInUIThread(() => Mp3Position = m_mediaPlayer.Position.Ticks);
        }

        #endregion

        #region PROPERTIES

        private string m_displayNamePlayedTrack;
        public string DisplayNamePlayedTrack
        {
            get { return m_displayNamePlayedTrack; }
            set
            {
                if (m_displayNamePlayedTrack != value)
                {
                    m_displayNamePlayedTrack = value;
                    RaisePropertyChanged("DisplayNamePlayedTrack");
                }
            }
        }

        public double ThumbPosition { get { return (m_mp3Position * 500 / m_mp3Length); } }

        private double m_mp3Position;
        public double Mp3Position
        {
            get { return m_mp3Position; }
            set
            {
                if (m_mp3Position != value)
                {
                    m_mp3Position = value;
                    RaisePropertyChanged("Mp3Position");
                    RaisePropertyChanged("ThumbPosition");
                }
            }
        }

        private double m_mp3Length;
        public double Mp3Length
        {
            get { return m_mp3Length; }
            set
            {
                if (m_mp3Length != value)
                {
                    m_mp3Length = value;
                    RaisePropertyChanged("Mp3Length");
                }
            }
        }

        private bool m_isLoading;
        public bool IsLoading
        {
            get { return m_isLoading; }
            set
            {
                if (m_isLoading != value)
                {
                    m_isLoading = value;
                    RaisePropertyChanged("IsLoading");
                }
            }
        }

        private BitmapImage m_currentImage;
        public BitmapImage CurrentImage
        {
            get { return m_currentImage; }
            set
            {
                if (m_currentImage != value)
                {
                    m_currentImage = value;
                    RaisePropertyChanged("CurrentImage");
                }
            }
        }

        #endregion

        public void Dispose()
        {
            if (m_mediaPlayerTimer != null) m_mediaPlayerTimer.Dispose();
        }
    }
}
